package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strconv"

	"github.com/xuri/excelize/v2"
)

type Property struct {
	Name       string `json:"name"`
	Label      string `json:"label"`
	AccessMode int    `json:"accessMode"`
	Type       int    `json:"type"`
	Params     struct {
		DbNumber  string `json:"dbNumber"`
		DataType  int    `json:"dataType"`
		StartAddr string `json:"startAddr"`
	} `json:"params"`
	Decimals int         `json:"decimals"`
	Unit     string      `json:"unit"`
	Formula  string      `json:"formula"`
	WFormula string      `json:"wFormula"`
	Script   string      `json:"script"`
	Value    interface{} `json:"value"`
}

type Device struct {
	Index      int        `json:"index"`
	Name       string     `json:"name"`
	Label      string     `json:"label"`
	Type       int        `json:"type"`
	Properties []Property `json:"properties,omitempty"`
}

func main() {
	// 读取Excel文件
	f, err := excelize.OpenFile("merged.xlsx")
	if err != nil {
		log.Fatalf("无法打开Excel文件: %v", err)
	}

	// 读取数据
	rows, err := f.GetRows("西门子PLC-S7物模型")
	if err != nil {
		log.Fatalf("无法读取工作表: %v", err)
	}

	// 创建设备映射
	devices := make(map[string]Device)

	// 跳过表头
	for rowIndex, row := range rows[1:] {
		if len(row) < 17 {
			log.Printf("警告: Row %d 数据不完整，将使用默认值补全",rowIndex+2)
			row = append(row, make([]string, 17-len(row))...)
		}

		index, _ := strconv.Atoi(row[0])
		deviceName := row[1]

		prop := Property{
			Name:       row[4],
			Label:      row[5],
			AccessMode: atoi(row[6]),
			Type:       atoi(row[7]),
			Params: struct {
				DbNumber  string `json:"dbNumber"`
				DataType  int    `json:"dataType"`
				StartAddr string `json:"startAddr"`
			}{
				DbNumber:  row[8],
				DataType:  atoi(row[9]),
				StartAddr: row[10],
			},
			Decimals: atoi(row[11]),
			Unit:     row[12],
			Formula:  row[13],
			WFormula: row[14],
			Script:   row[15],
			Value:    row[16],
		}

		if device, exists := devices[deviceName]; exists {
			device.Properties = append(device.Properties, prop)
			devices[deviceName] = device
		} else {
			devices[deviceName] = Device{
				Index:      index,
				Name:       deviceName,
				Label:      row[2],
				Type:       atoi(row[3]),
				Properties: []Property{prop},
			}
		}
	}

	// 将数据转换为JSON
	output, err := json.MarshalIndent(devices, "", "  ")
	if err != nil {
		log.Fatalf("无法编码JSON: %v", err)
	}

	// 保存JSON文件
	err = os.WriteFile("exported.json", output, 0644)
	if err != nil {
		log.Fatalf("无法写入JSON文件: %v", err)
	}

	fmt.Println("导出成功，JSON文件已保存到 exported.json")
}

func atoi(s string) int {
	i, err := strconv.Atoi(s)
	if err != nil {
		return 0
	}
	return i
}
